﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Runnergame.Model;
using runnergamexna.Model;

namespace Runnergame.Model
{
    class Collision
    { 
        //https://code.google.com/p/1dv437arkanoid/source/browse/trunk/Collisions/Collisions2/Model/Model.cs
            
            public Level m_level;
            public Player m_player;

            public Collision (Player player, Level level)
	        {
                m_player = player;
                m_level = level;
	        }         

            public bool didCollide(Vector2 a_centerBottom, Vector2 a_size)
            {                
                FloatRectangle occupiedArea = FloatRectangle.createFromCenterBottom(a_centerBottom, a_size);
                if (m_level.IsCollidingAt(occupiedArea))
                {
                    return true;
                }
                return false;
            }

            public CollisionDetails getCollisionDetails(Vector2 a_oldPos, Vector2 a_newPosition, Vector2 a_size, Vector2 a_velocity)
            {
                CollisionDetails ret = new CollisionDetails(a_oldPos, a_velocity);

                Vector2 slidingXPosition = new Vector2(a_newPosition.X, a_oldPos.Y); //Y movement ignored
                Vector2 slidingYPosition = new Vector2(a_oldPos.X, a_newPosition.Y); //X movement ignored

                if (didCollide(slidingXPosition, a_size) == false)
                {
                    return doOnlyXMovement(ref a_velocity, ret, ref slidingXPosition);
                }
                else if (didCollide(slidingYPosition, a_size) == false)
                {

                    return doOnlyYMovement(ref a_velocity, ret, ref slidingYPosition);
                }
                else
                {
                    return doStandStill(ret, a_velocity);
                }

            }

            private static CollisionDetails doStandStill(CollisionDetails ret, Vector2 a_velocity)
            {
                if (a_velocity.Y > 0)
                {
                    ret.m_hasCollidedWithGround = true;
                }
                ret.m_speedAfterCollision = new Vector2(0, 0);
                return ret;
            }

            private static CollisionDetails doOnlyYMovement(ref Vector2 a_velocity, CollisionDetails ret, ref Vector2 slidingYPosition)
            {
                a_velocity.X *= -0.5f; //bounce from wall
                ret.m_speedAfterCollision = a_velocity;
                ret.m_positionAfterCollision = slidingYPosition;
                return ret;
            }

            private static CollisionDetails doOnlyXMovement(ref Vector2 a_velocity, CollisionDetails ret, ref Vector2 slidingXPosition)
            {
                ret.m_positionAfterCollision = slidingXPosition;
                //did we slide on ground?
                if (a_velocity.Y > 0)
                {                   
                    ret.m_hasCollidedWithGround = true;
                }

                ret.m_speedAfterCollision = doSetSpeedOnVerticalCollision(a_velocity);
                return ret;
            }
            private static Vector2 doSetSpeedOnVerticalCollision(Vector2 a_velocity)
            {
                //did we collide with ground?
                if (a_velocity.Y > 0)
                {
                    a_velocity.Y = 0; //no bounce
                }
                else
                {
                    //collide with roof
                    a_velocity.Y *= -1.0f;
                }

                a_velocity.X *= 0.10f;

                return a_velocity;
            }
        }
    }
